#[cfg(test)]
mod test_chapter5 {
    use std::fs::read;
    use std::fmt::Debug;
    use std::rc::{Rc, Weak};
    use std::cell::{RefCell, Cell};
    use std::borrow::Cow;
    use std::thread;

    #[test]
    fn test_for_scope() {
        let v = vec![1, 2, 3];
        for i in v {
            println!("{:?}", i);
//            println!("{:?}", v);
        }
    }

    #[test]
    fn test_bubble_sort() {

        // 冒泡排序
        fn bubble_sort(a: &mut Vec<i32>) {
            let mut n = a.len();
            while n > 0 {
                // 初始化遍历游标， max_ptr 始终指向最大值
                let (mut i, mut max_ptr) = (1, 0);
                // 冒泡开始，如果前者大于后者，则互换位置，并设置当前最大值游标
                while i < n {
                    if a[i - 1] > a[i] {
                        a.swap(i - 1, i);
                        max_ptr = i;
                    }
                    i += 1;
                }
                // 本次遍历的最大值位置也是下一轮冒泡的终点
                n = max_ptr;
            }
        }

        let mut a = vec![1, 4, 5, 3, 2];
        bubble_sort(&mut a);
        println!("{:?}", a);
    }

    #[test]
    fn test_compute() {
        fn compute (input: &u32, output: &mut u32) {
            if *input > 10 {
                *output = 1;
            }
            if *input > 5 {
                *output *= 2;
            }
        }

        let i = 20;
        let mut o = 5;
        compute(&i, &mut o);
    }

    #[test]
    fn test_live_time() {
        fn the_longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
            if s1.len() > s2.len() {
                s1
            }else {
                s2
            }
        }

        let s1 = String::from("Rust");
        let s1_r = &s1;
        {
            let s2 = String::from("C");
            let res = the_longest(s1_r, &s2);
            println!("{} is the longest", res);
        }
    }

    // 包含引用类型成员的结构体也需要标注生命周期参数
    #[test]
    fn test_ref_struct() {
        #[derive(Debug)]
        struct Foo<'a> {
            part: &'a str,
        }

        impl<'a> Foo<'a> {
            fn split_first(s: &'a str) -> &'a str {
                s.split(',').next().expect("Could not find a ','")
            }
            fn new(s: &'a str) -> Self {
                Foo{part: Foo::split_first(s)}
            }

            // 满足生命周期的省略规则
            fn get_part(&self) -> &str {
                self.part
            }
        }

        let words = String::from("Sometimes think, the greatest sorrow than older");
        println!("{:?}", Foo::new(words.as_str()));
    }

    // 省略生命周期参数的示例
    #[test]
    fn test_first_word() {
        fn first_word(s: &str) -> &str {
            let bytes = s.as_bytes();
            for (i, &item) in bytes.iter().enumerate() {
                if item == b' ' {
                    return &s[0..i];
                }
            }
            &s[..]
        }

        println!("{:?}", first_word("hello Rust"));
    }

    // p145 声明周期限定
    #[test]
    fn test_life_limit() {
        #[derive(Debug)]
        struct Ref<'a, T: 'a>(&'a T);
        fn print<T>(t: T) where T: Debug {
            println!("`print`: t is {:?}", t);
        }
        fn print_ref<'a, T>(t: &'a T) where T: Debug + 'a {
            println!("`print_ref`: t is {:?}", t);
        }

        let x = 7;
        let ref_x = Ref(&x);
        print_ref(&ref_x);
        print(ref_x);
    }

    // Rc 示例
    #[test]
    fn test_rc() {
        let x = Rc::new(45);
        let y1 = x.clone();// 增加强引用计数
        let y2 = x.clone();// 增加强引用计数
        println!("{:?}", Rc::strong_count(&x));
        println!("{:?}", Rc::strong_count(&y1));

        let w = Rc::downgrade(&x);// 增加弱引用计数
        println!("{:?}", Rc::weak_count(&x));
//        println!("{:?}", Rc::weak_count(&w));

        let y3 = &*x; // 不增加计数
        println!("{}", 100 - *x);
    }

    // 利用Weak<T> 解决 循环引用的内存泄漏问题
    #[test]
    fn test_weak() {
        struct Node {
            next: Option<Rc<RefCell<Node>>>,
            head: Option<Weak<RefCell<Node>>>,
        }

        impl Drop for Node {
            fn drop(&mut self) {
                println!("Dropping!");
            }
        }

        let first = Rc::new(RefCell::new(Node{next: None, head: None}));
        let second = Rc::new(RefCell::new(Node{next: None, head: None}));
        let third = Rc::new(RefCell::new(Node{next: None, head: None}));
        first.borrow_mut().next = Some(second.clone());
        second.borrow_mut().next = Some(third.clone());
        third.borrow_mut().head = Some(Rc::downgrade(&first));
    }

    // 使用 Cell<T> 实现字段级可变
    #[test]
    fn test_cell() {
        struct Foo {
            x: u32,
            y: Cell<u32>,
        }

        let foo = Foo{x: 1, y: Cell::new(3)};
        assert_eq!(1, foo.x);
        assert_eq!(3, foo.y.get());
        foo.y.set(5);
        assert_eq!(5, foo.y.get());
    }

    // RefCell<T> 内部可变性示例
    #[test]
    fn test_refcell() {
        let x = RefCell::new(vec![1, 2, 3, 4]);
        println!("{:?}", x.borrow());
        x.borrow_mut().push(5);
        println!("{:?}", x.borrow());
    }

    // Cow<T> 示例
    #[test]
    fn test_cow() {
        fn abs_all(input: &mut Cow<[i32]>) {
            for i in 0..input.len() {
                let v = input[i];
                if v < 0 {
                    input.to_mut()[i] = -v;
                }
            }
        }

        fn abs_sum(ns: &[i32]) -> i32 {
            let mut lst = Cow::from(ns);
            abs_all(&mut lst);
            lst.iter().fold(0, |acc, &n| acc + n)
        }

        // 这里没有可变需求，所以不会克隆
        let s1 = [1, 2, 3];
        let mut i1 = Cow::from(&s1[..]);
        abs_all(&mut i1);
        println!("IN: {:?}", s1);
        println!("OUT: {:?}", i1);

        // 这里有可变需求，所以会克隆。注意：借用数据被克隆为了新的对象
        // s2 != i2, 实际上， s2 不可变，也不会被改变
        let s2 = [1, 2, 3, -45, 5];
        let mut i2 = Cow::from(&s2[..]);
        abs_all(&mut i2);
        println!("IN: {:?}", s2);
        println!("OUT: {:?}", i2);

        // 这里不会克隆，因为数据本身拥有所有权。注意：在本例中，v1 本身就是可变的
        let mut v1 = Cow::from(vec![1, 2, -3, 4]);
        abs_all(&mut v1);
        println!("IN/OUT: {:?}", v1);

        // 没有可变需求，所以没有克隆
        let s3 = [1, 3, 5, 6];
        let sum1 = abs_sum((&s3[..]));
        println!("{:?}", s3);
        println!("{}", sum1);

        // 这里有可变需求，所以发生了克隆
        let s4 = [1, -3, 5, -6];
        let sum2 = abs_sum(&s4[..]);
        println!("{:?}", s4);
        println!("{}", sum2);
    }

    // 利用 Cow<T> 来统一实现规范
    #[test]
    fn test_cow_same_all() {
        #[derive(Debug)]
        struct Token<'a> {
            raw: Cow<'a, str>,
        }

        impl<'a> Token<'a> {
            pub fn new<S>(raw: S) -> Token<'a> where S: Into<Cow<'a, str>> {
                Token{raw: raw.into()}
            }
        }

        let token = Token::new("abc123");
        let token = Token::new("api.example.io".to_string());
        thread::spawn(move || {
            println!("token: {:?}", token);
        }).join().unwrap();
    }
}



























